﻿--[[
	Widget name	  	PropertyList
	Author     	 	Kurapica
--]]

-- PropertyList
do
	IGAS:NewAddon("IGAS_Studio")

    ------------------------------------------------------
	-- PropertyList
	------------------------------------------------------
	local _WidgetName = "PropertyList"
    local _Base = "Frame"

	local _PropertyList

	-- Scripts
	local _FrameBackdrop = {
        bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 16,
        insets = { left = 3, right = 3, top = 3, bottom = 3 }
	}

	local _SelFrame
	local _ObjectType
	local _IsContainer

	-- Chooser
	local level = 0
	local orderT = {}

	local nodeHeight = 26
	local nodeIndent = 10

	local function FixHeightSeparator(self)
		local height = nodeHeight

		if self:GetChild("PropertySet1") then
			if self.__NodeNum > 0 then
				for i = 1, self.__NodeNum do
					if self:GetChild("PropertySet"..i) and self:GetChild("PropertySet"..i).Visible then
						height = height + self:GetChild("PropertySet"..i).Height
					end
				end
			end
		end

		self.Height = height
	end

	local function FixHeightList(self)
		self.ScrollForm:FixHeight()
	end

	-- PropertySet's Scripts
	local function PropertySet_OnPropertyChanged(self, object, prop, value, oldvalue)
		_PropertyList:Fire("OnPropertyChanged", GetShadowFrame(object), prop, value, oldvalue)
	end

	-- Refresh List
	local function RefreshList(frame, container, objectType, isContainer)
		local propertySpt
		local propertySet
		local property
		local propertyName
		local truePropertys = (GetTrueObject(frame)).Property
		local propType

		local index = 0

		if not isContainer and objectType.Base then
			RefreshList(frame, container, objectType.Base)
		end

		level = level + 1
		propertySpt = CreateFrame(Widget.PropertySeparator, "PropertySeparator"..level, container)
		propertySpt.Visible = true
		propertySpt.ToggleState = true
		propertySpt.Text = (isContainer and "Container") or objectType.WidgetName

		if not isContainer then
			for propertyName in pairs(objectType.Property) do
				if not orderT[propertyName] then
					orderT[propertyName] = true

					property = truePropertys[propertyName]
					
					propType = IGAS:GetPropertyType(property.Type)
					
					propType  = propType and propType.Type

					if propType and property["Get"] and property["Set"] and
						(propType == "number" or propType == "string" or propType == "boolean" or propType == "enum" or	propType == "table") then
						-- Can be list in the propertyList
						index = index + 1
						propertySet = CreateFrame(Widget.PropertySet, "PropertySet"..index, propertySpt)
						propertySet.Visible = true

						propertySet:SetProperty(frame, propertyName)

						propertySet.OnPropertyChanged = PropertySet_OnPropertyChanged
					end
				end
			end
		else
			if frame["Height"] then
				index = index + 1
				propertySet = CreateFrame(Widget.PropertySet, "PropertySet"..index, propertySpt)
				propertySet.Visible = true

				propertySet:SetProperty(frame, "Height")

				propertySet.OnPropertyChanged = PropertySet_OnPropertyChanged
			end
		end

		-- Hide useless propertySet
		index = index + 1
		while propertySpt:GetChild("PropertySet"..index) do
			propertySpt:GetChild("PropertySet"..index):SetProperty(nil, nil)
			propertySpt:GetChild("PropertySet"..index).Visible = false
			index = index + 1
		end

		FixHeightSeparator(propertySpt)
	end

	-- Advance settings for item
	local function Advance_OnClick(self, button)
		if self.Parent.SelectedFrame then
			self.Parent:Fire("OnFrameAdvance", self.Parent.SelectedFrame)
		end
	end

	-- Register Event
	local function Reg_OnClick(self)
		if self.Parent.SelectedFrame then
			self:FireEvent("IGAS_STUDIO_REGISTER_EVENT", self.Parent.SelectedFrame, false)
		end
	end

	-- Delete Item
	local function Delete_OnClick(self, button)
		if self.Parent.SelectedFrame then
			self.Parent:Fire("OnFrameDispose", self.Parent.SelectedFrame)
		end
	end

	-- ScriptType
	local _ScriptType = {
		["OnPropertyChanged"] = true,
		["OnFrameDispose"] = true,
		["OnFrameAdvance"] = true,
	}

	-- Function
	local _Function = {
    }

	-- Property
	local _Property = {
		-- SelectedFrame
		["SelectedFrame"] = {
			["Set"] = function(self, frame)
				local container = self.ScrollForm.Container

				if _SelFrame == frame then
					return
				end

				_SelFrame = frame

				if _SelFrame then
					if not _FrameInfoList[_SelFrame] then
						error("Not exist _FrameInfoList[".._SelFrame.Name.."]", 2)
					end
					self:GetChild("Delete").Enabled = not _FrameInfoList[_SelFrame].IsContainer
					if Advance[GetTrueObject(_SelFrame)] then
						self:GetChild("Advance").Enabled = true
					else
						self:GetChild("Advance").Enabled = false
					end
					self:GetChild("Reg").Enabled = GetTrueFrame(_SelFrame):IsObjectType("Frame")
				else
					self:GetChild("Delete").Enabled = false
					self:GetChild("Advance").Enabled = false
					self:GetChild("Reg").Enabled = false
				end

				-- Init
				level = 0
				wipe(orderT)
				orderT["Parent"] = true
				
				self:GetChild("ScrollForm").Value = 0

				-- Refresh
				if _SelFrame then
					RefreshList(GetTrueFrame(_SelFrame), container, GetTrueObject(_SelFrame), _FrameInfoList[_SelFrame].IsContainer)
				end

				-- Hide useless propertySet
				if container.__NodeNum > level then
					local index = container.__NodeNum

					while index > level do
						container:GetChild("PropertySeparator"..index).ToggleState = false
						container:GetChild("PropertySeparator"..index).Visible = false
						index = index - 1
					end
				end

				FixHeightList(self)
			end,

			["Get"] = function(self)
				return _SelFrame
			end,

			["Type"] = IGAS:GetPropertyType("Object"),
		},
    }

    -- New
    local function _New(name, parent)
        local frame = CreateFrame(_Base, name, parent)

		-- So, we only need one.
		if _PropertyList then
			return _PropertyList
		end

		frame.Width =200
		frame.Height = 400

		frame.Movable = true
		frame.Resizable = true
		frame.FrameStrata = "DIALOG"
		frame.Toplevel = true
		frame.MouseEnabled = true
		frame.MouseWheelEnabled = true

		frame:SetBackdrop(_FrameBackdrop)
		frame:SetBackdropColor(0,0,0,1)
		frame:SetMinResize(200,200)
		frame:SetMaxResize(600,1000)

		local btnAdvance = CreateFrame("NormalButton", "Advance", frame)
		btnAdvance:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, -4)
		btnAdvance:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, -4)
		btnAdvance.Height = 26
		btnAdvance.Style = "NORMAL"
		btnAdvance.Enabled = false
		btnAdvance.Text = L["Advance"]

		local btnReg = CreateFrame("NormalButton", "Reg", frame)
		btnReg:SetPoint("TOPLEFT", btnAdvance, "BOTTOMLEFT", 0, -4)
		btnReg:SetPoint("TOPRIGHT", btnAdvance, "BOTTOMRIGHT", 0, -4)
		btnReg.Height = 26
		btnReg.Style = "NORMAL"
		btnReg.Enabled = false
		btnReg.Text = L["Register"]


		local btnDelete = CreateFrame("NormalButton", "Delete", frame)
		btnDelete:SetPoint("TOPLEFT", btnReg, "BOTTOMLEFT", 0, -4)
		btnDelete:SetPoint("TOPRIGHT", btnReg, "BOTTOMRIGHT", 0, -4)
		btnDelete.Height = 26
		btnDelete.Style = "NORMAL"
		btnDelete.Enabled = false
		btnDelete.Text = L["Delete"]

		local scrollForm = CreateFrame("ScrollForm", "ScrollForm", frame)
		scrollForm:SetPoint("TOPLEFT", btnDelete, "BOTTOMLEFT", 0, -4)
		scrollForm:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 10)
		scrollForm:SetBackdrop(nil)
		scrollForm.ValueStep = 26
		scrollForm.Container.__NodeNum = 0

		btnAdvance.OnClick = Advance_OnClick
		btnReg.OnClick = Reg_OnClick
		btnDelete.OnClick = Delete_OnClick

		_PropertyList = frame

        return frame
    end

    local _WidgetInfo = {
        ["WidgetName"] = _WidgetName,
        ["Base"] = _Base,
        ["Function"] = _Function,
        ["Property"] = _Property,
        ["ScriptType"] = _ScriptType,
        ["New"] = _New,
    }

    Widget[_WidgetName] = IGAS:NewWidget(_WidgetInfo)
end